using Unity.Collections;
using Unity.Entities;
using UnityEngine;

namespace PathFinding
{
    public struct AStarFunnel
    {
        public AStarFunnel(int dd,Allocator allocator)
        {}
        public bool TryCreateStraightPath(PathQuery query, NativeSlice<PathPolygonId> path, Vector3 from, Vector3 to)
        {
            return true;
        }
        
        /// <summary>
        /// Returns locations array of the path.
        /// </summary>
        /// <returns>Returns array of locations.</returns>
        public NativeSlice<PathLocation> AsLocations()
        {
            //return m_Corners.Slice(0, m_Length);
            throw new System.NotImplementedException();
        }
        
        public float GetCornersDistance()
        {
            // float distance = 0;
            // for (int i = 1; i < m_Length; ++i)
            // {
            //     distance += math.distance(m_Corners[i - 1].position, m_Corners[i].position);
            // }
            // return distance;
            throw new System.NotImplementedException();
        }
        
        public bool IsEndReachable => throw new System.NotImplementedException();
    }
    
        /// <summary>
    /// State of the path.
    /// </summary>
    public enum AgentPathState
    {
        /// <summary>
        /// Waiting for new NavMesh path requested to be handled.
        /// </summary>
        WaitingNewPath,
        /// <summary>
        /// NavMesh path building is in progress.
        /// </summary>
        InProgress,
        FinishedFullPath,
        FinishedPartialPath,
        /// <summary>
        /// NavMesg path building failed. See editor console for more information.
        /// </summary>
        Failed,
        /// <summary>
        /// NavMesh path is no longer valid.
        /// </summary>
        InValid,
    }
    /// <summary>
    /// The status of navmesh query.
    /// </summary>
    public enum MQueryStatus
    {
        None,
        /// <summary>
        /// Path is allocated.
        /// </summary>
        Allocated,
        /// <summary>
        /// Path is in progress.
        /// </summary>
        InProgress,
        /// <summary>
        /// Failed to construct path.
        /// </summary>
        Failed,
        /// <summary>
        /// Full path is finished, where destination is reachable.
        /// </summary>
        FinishedFullPath,
        /// <summary>
        /// Partial path is finished, where it leads close enough to destination.
        /// </summary>
        FinishedPartialPath,
        /// <summary>
        /// Path is already released.
        /// </summary>
        Free,
    }

    public struct AgentPath : IComponentData, IEnableableComponent
    {
        /// <summary>
        /// State of the path.
        /// </summary>
        public AgentPathState State;
        /// <summary>
        /// Query handle of current requested path.
        /// </summary>
        public PathQueryHandle QueryHandle;
        /// <summary>
        /// The type ID for the agent in NavMesh.
        /// </summary>
        public int AgentTypeId;
        /// <summary>
        /// Specifies which NavMesh areas are passable. Changing areaMask will make the path stale (see isPathStale).
        /// </summary>
        public int AreaMask;
        /// <summary>
        /// Should the agent attempt to acquire a new path if the existing path becomes invalid?
        /// </summary>
        public bool AutoRepath;
        /// <summary>
        /// Constraint agent to be on the surface. It is useful to disable then used with physics, to allow more freedom motion and precision.
        /// </summary>
        public bool Grounded;
        /// <summary>
        /// Maximum distance on each axis will be used when attempting to map the agent's position or destination onto navmesh.
        /// The higher the value, the bigger the performance cost.
        /// </summary>
        public Vector3 MappingExtent;
        /// <summary>
        /// Current location of the agent on NavMesh.
        /// </summary>
        public PathLocation Location;
        /// <summary>
        /// End location of the agent on NavMesh.
        /// </summary>
        public PathLocation EndLocation;

        public bool HasPath => State == AgentPathState.FinishedFullPath || State == AgentPathState.FinishedPartialPath;
        public bool HasPartialPath => State == AgentPathState.FinishedPartialPath;
        public bool HasFullPath => State == AgentPathState.FinishedFullPath;

        /// <summary>
        /// Returns default configuration.
        /// </summary>
        public static AgentPath Default => new()
        {
            State = AgentPathState.FinishedFullPath,
            AreaMask = -1,
            AutoRepath = true,
            MappingExtent = Vector3.one * 10,
            Grounded = true,
        };
    }
    
    public struct PathNode : IBufferElementData
    {
        public PathPolygonId Value;
        public Vector3 position;
    }

    public struct PathAreaCost : IBufferElementData
    {
        public float Value;
    }
}